package common.interfaces;

import java.sql.SQLException;
import java.util.Collection;

import registration.Consensus;
import user.User;

import common.Pair;
import common.exceptions.*;

/**
 * Manages the votes on consensuses
 * 
 * @author Gal Lalouche
 */
public interface IVoteManager extends IPersistent {
	/**
	 * Votes on the consensus; repeating votes with the same user and consensus will overwrite themselves
	 * 
	 * @param con The consensus to vote on
	 * @param user The user doing the vote
	 * @param vote The vote
	 * @throws InvalidConsensusException
	 * @throws InvalidUserException
	 * @throws IllegalArgumentException If the user is not registered to the event
	 * @throws SQLException
	 */
	void vote(Consensus con, User user, boolean vote) throws InvalidConsensusException, InvalidUserException,
			SQLException;
	
	/**
	 * @param con The consensus to check
	 * @return <code>true</code> if a consensus has been reached on true, <code>false</code> if on false,
	 *         <code>null</code> otherwise. a consensus will be considered reached if all the users registered have
	 *         voted and they have all voted the same.
	 * @throws InvalidConsensusException
	 * @throws SQLException
	 */
	Boolean getConsensusStatus(Consensus con) throws InvalidConsensusException, SQLException;
	
	/**
	 * Gets the last vote cast by the user.
	 * 
	 * @param con The consensus the vote was cast on.
	 * @param user The user voting
	 * @return The last vote cast by the user, or <code>null</code> if the user has not yet voted
	 * @throws InvalidConsensusException
	 * @throws InvalidUserException
	 * @throws IllegalArgumentException If the user is not registered to the event
	 * @throws SQLException
	 */
	Boolean getVote(Consensus con, User user) throws InvalidConsensusException, InvalidUserException, SQLException;
	
	/**
	 * Gets all votes cast on the consensus
	 * 
	 * @param con The consensus
	 * @return all votes cast on the consensus
	 * @throws InvalidConsensusException
	 * @throws SQLException
	 */
	Collection<Pair<User, Boolean>> getAllVotes(Consensus con) throws InvalidConsensusException, SQLException;
	
	/**
	 * Remove (resets) all votes cast on the consensus
	 * 
	 * @param con The consensus
	 * @throws SQLException
	 */
	void removeAllVotes(Consensus con) throws SQLException;
	
	/**
	 * Removes all votes cast by a user, on any consensus
	 * 
	 * @param user The user
	 * @throws SQLException
	 */
	void removeAllVotes(User user) throws SQLException;
}
